package com.panda.web.controller.order;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import com.panda.common.core.domain.R;
import com.panda.web.domain.vo.OrderCount;
import com.panda.web.excel.utils.ExcelUtils;
import com.panda.web.entity.order.WechatOrder;
import com.panda.web.entity.product.OpenidProduct;
import com.panda.web.entity.product.Product;
import com.panda.web.excel.domain.OrderExcel;
import com.panda.web.mapper.order.WechatOrderMapper;
import com.panda.web.mapper.product.OpenidProductMapper;
import com.panda.web.mapper.product.ProductMapper;
import com.panda.web.service.order.IWechatOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.panda.web.utils.pageutils.PageResult;

import com.panda.common.annotation.Log;
import com.panda.common.core.controller.BaseController;
import com.panda.common.core.domain.AjaxResult;
import com.panda.common.enums.BusinessType;
import com.panda.web.domain.dto.OrderDTO;
import com.panda.web.domain.vo.OrderVO;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付订单Controller
 *
 * @author cpanda
 * @date 2025-02-27
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/web/order")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WechatOrderController extends BaseController {
    private final IWechatOrderService orderService;

    @Autowired
    private WechatOrderMapper orderMapper;
    @Autowired
    private OpenidProductMapper openidProductMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ExcelUtils excelUtils;

    @PostMapping("/hdce")
    public R hdcs(@RequestBody WechatOrder order) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = simpleDateFormat.format(date);
        Product product = productMapper.selectById(order.getProductId());//产品表
        OpenidProduct openidProduct = openidProductMapper.findByProductIdAndOpenId(order.getOpenid(), order.getProductId());

        //判断是否为空，为空 说明第一次购买这个产品，否则不是第一次
        if (openidProduct != null) {//更新原商品状态为可使用
            if (Objects.equals(openidProduct.getStatus(), "0")) {//说明没到期
                //在该套餐的上加时间
                if (openidProduct.getProductId() == 2 || openidProduct.getProductId() == 3 || openidProduct.getProductId() == 4) {
                    openidProduct.setDay(String.valueOf(Integer.valueOf(openidProduct.getDay()) + Integer.valueOf(openidProduct.getProductType())));
                }
                if (product.getProductId() == 2 || product.getProductId() == 3) {
                    openidProduct.setAiCount(openidProduct.getAiCount() + product.getAiCount());
                }
                openidProduct.setCount(openidProduct.getCount() + 1);
                openidProductMapper.updateById(openidProduct);
            } else {//到期了
                openidProduct.setStatus("0");
                openidProduct.setCreationTime(formattedDate);//新购买时间，更新购买次数
                if (product.getProductId() == 2 || product.getProductId() == 3) {
                    openidProduct.setAiCount(openidProduct.getAiCount() + product.getAiCount());
                }
                openidProduct.setCreateTime(date);
                openidProduct.setCount(openidProduct.getCount() + 1);
                openidProductMapper.updateById(openidProduct);
            }
//                    openidProduct.setStatus("0");
//                    openidProduct.setCreationTime(formattedDate);//新购买时间，更新购买次数
//                    if (product.getProductId()==2||product.getProductId()==3){
//                        openidProduct.setAiCount(openidProduct.getAiCount()+product.getAiCount());
//                    }
//                    openidProduct.setCreateTime(date);
//                    openidProduct.setCount(openidProduct.getCount() + 1);
//                    openidProductMapper.updateById(openidProduct);
        } else {
            OpenidProduct openidProductNew = new OpenidProduct();
            openidProductNew.setOpenid(order.getOpenid());
            openidProductNew.setProductId(order.getProductId());
            openidProductNew.setProductType(product.getProductType());
            openidProductNew.setProductName(product.getProductName());
            openidProductNew.setProductPrice(product.getProductPrice());
            openidProductNew.setAiCount(product.getAiCount());
            openidProductNew.setDay(product.getProductType());
            openidProductNew.setCreateTime(date);
            openidProductNew.setCreationTime(formattedDate);
            openidProductNew.setCount(1);
            openidProductMapper.insert(openidProductNew);
        }
        return R.ok();
    }

    /**
     * 调用微信支付接口
     *
     * @param order
     * @return
     */
    @PostMapping("/createOrder")
    public R createOrder(@RequestBody WechatOrder order) throws Exception {
        Map<String, String> aaaa = orderService.createOrder(order);
        return R.ok(aaaa, 200, "ok");
    }

    //支付回调通知接口
    @PostMapping("/notify")
    public ResponseEntity<String> handleWeChatPaymentCallback(HttpServletRequest request) {
        Date date = new Date();
        SimpleDateFormat stringDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = stringDate.format(date);

        try {
            // 1. 解析微信支付回调的XML数据
            Map<String, String> resultData = parseXmlToMap(request);

            // 2. 验证签名
            String sign = resultData.get("sign");
            String apiKey = "Shandongweichangwangluo123456789"; // 从配置中获取密钥
            String calculatedSign = generateSignature(resultData, apiKey);
            if (!calculatedSign.equals(sign)) {
                String errorResponse = "<xml><return_code>FAIL</return_code><return_msg>签名验证失败</return_msg></xml>";
                return ResponseEntity.ok().body(errorResponse);
            }

            // 3. 获取回调的支付状态
            String returnCode = resultData.get("return_code");
            String resultCode = resultData.get("result_code");
            String tradeState = resultData.get("trade_state"); // 支付状态
            String orderId = resultData.get("out_trade_no"); // 订单号
            String transactionId = resultData.get("transaction_id"); // 微信支付订单号

            // 4. 判断支付是否成功
            if (!"SUCCESS".equals(returnCode) || !"SUCCESS".equals(resultCode)) {
                String responseXml = "<xml><return_code>FAIL</return_code><return_msg>支付失败</return_msg></xml>";
                return ResponseEntity.ok().body(responseXml);
            }

            // 5. 查询订单
            WechatOrder order = orderMapper.findByOrderId(orderId);
            if (order == null) {
                String errorResponse = "<xml><return_code>FAIL</return_code><return_msg>订单不存在</return_msg></xml>";
                return ResponseEntity.ok().body(errorResponse);
            }

            // 6. 幂等性处理：如果订单已经是“已支付”状态，直接返回成功
            if ("已支付".equals(order.getPayStatus())) {
                String responseXml = "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
                return ResponseEntity.ok().body(responseXml);
            }

//            // 7. 更新订单状态
//            order.setPayStatus("已支付");
//            order.setTransactionId(transactionId);
//            order.setPayTime(new Date());
//            orderMapper.updateById(order);
//            log.info("更新后的订单信息：{}", order);
            if (order != null) {
                order.setPayStatus("已支付");
                order.setTransactionId(transactionId);
                order.setPayTime(new Date());
                orderMapper.updateById(order);
                //添加用户已购买产品的产品表
                Product product = productMapper.selectById(order.getProductId());//产品表
                OpenidProduct openidProduct = openidProductMapper.findByProductIdAndOpenId(order.getOpenid(), order.getProductId());

                //判断是否为空，为空 说明第一次购买这个产品，否则不是第一次
                if (openidProduct != null) {//更新原商品状态为可使用
                    if (Objects.equals(openidProduct.getStatus(), "0")) {//说明没到期
                        //在该套餐的上加时间
                        if (openidProduct.getProductId() == 2 || openidProduct.getProductId() == 3 || openidProduct.getProductId() == 4 || openidProduct.getProductId() == 8 || openidProduct.getProductId() == 9) {
                            openidProduct.setDay(String.valueOf(Integer.valueOf(openidProduct.getDay()) + Integer.valueOf(openidProduct.getProductType())));
                        }
                        if (product.getProductId() == 2 || product.getProductId() == 3 ) {
                            openidProduct.setAiCount(openidProduct.getAiCount() + product.getAiCount());
                        }
                        openidProduct.setCount(openidProduct.getCount() + 1);
                        openidProductMapper.updateById(openidProduct);
                    } else {//到期了
                        openidProduct.setStatus("0");
                        openidProduct.setCreationTime(formattedDate);//新购买时间，更新购买次数
                        if (product.getProductId() == 2 || product.getProductId() == 3) {
                            openidProduct.setAiCount(openidProduct.getAiCount() + product.getAiCount());
                        }
                        openidProduct.setCreateTime(date);
                        openidProduct.setCount(openidProduct.getCount() + 1);
                        openidProductMapper.updateById(openidProduct);
                    }


//                    openidProduct.setStatus("0");
//                    openidProduct.setCreationTime(formattedDate);//新购买时间，更新购买次数
//                    if (product.getProductId()==2||product.getProductId()==3){
//                        openidProduct.setAiCount(openidProduct.getAiCount()+product.getAiCount());
//                    }
//                    openidProduct.setCreateTime(date);
//                    openidProduct.setCount(openidProduct.getCount() + 1);
//                    openidProductMapper.updateById(openidProduct);
                } else {
                    OpenidProduct openidProductNew = new OpenidProduct();
                    openidProductNew.setOpenid(order.getOpenid());
                    openidProductNew.setProductId(order.getProductId());
                    openidProductNew.setProductType(product.getProductType());
                    openidProductNew.setProductName(product.getProductName());
                    openidProductNew.setProductPrice(product.getProductPrice());
                    openidProductNew.setAiCount(product.getAiCount());
                    openidProductNew.setDay(product.getProductType());
                    openidProductNew.setCreateTime(date);
                    openidProductNew.setCreationTime(formattedDate);
                    openidProductNew.setCount(1);
                    openidProductMapper.insert(openidProductNew);
                }
            }
            // 8. 返回微信要求的成功响应
            String responseXml = "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
            return ResponseEntity.ok().body(responseXml);

        } catch (
                Exception e) {
            log.error("微信支付回调处理异常", e);
            String errorResponse = "<xml><return_code>FAIL</return_code><return_msg>系统错误</return_msg></xml>";
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    private static String generateSignature(Map<String, String> params, String apiKey) throws Exception {
        // 1. 按参数名的字典序排序
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);

        // 2. 拼接参数（排除 sign 字段）
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            if (!"sign".equals(key) && params.get(key) != null && !params.get(key).isEmpty()) {
                sb.append(key).append("=").append(params.get(key)).append("&");
            }
        }
        sb.append("key=").append(apiKey);

        // 3. 使用 MD5 生成签名
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(sb.toString().getBytes("UTF-8"));
        return byteArrayToHexString(digest).toUpperCase();
    }

    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    private Map<String, String> parseXmlToMap(HttpServletRequest request) throws Exception {
        try (InputStream inputStream = request.getInputStream()) {
            if (inputStream == null) {
                throw new IOException("输入流为空");
            }

            // 使用dom4j解析XML
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);

            // 获取所有子节点
            Map<String, String> map = new HashMap<>();
            List<Element> elements = document.getRootElement().elements();
            for (Element element : elements) {
                map.put(element.getName(), element.getTextTrim());
            }

            return map;
        } catch (Exception e) {
            log.error("解析微信支付回调XML数据失败", e);
            throw new Exception("解析XML失败", e);
        }
    }


    /**
     * 退款
     */
    @PostMapping("/wx/refund")
    public R wxRefund(@RequestBody OrderDTO dto) throws Exception {
        return R.ok(orderService.refundOrder(dto));
    }

    /**
     * 微信退款回调
     *
     * @return R
     */
    @Log(title = "微信退款回调")
    @PostMapping("/return")
    public R refundPayNotify(HttpServletRequest request) throws Exception {
        return R.ok(orderService.refundNotify(request), 200, "ok"); //注意：回调接口需要暴露到公网上，且要放开token验证
    }


    /**
     * 查询微信支付订单列表
     */
    @GetMapping("/listyuan")
    public PageResult<OrderVO> List(OrderDTO dto,
                                    @RequestParam("pageNum") Integer pageNum,
                                    @RequestParam("pageSize") Integer pageSize) {
        //返回分页信息
        PageResult<OrderVO> voList = orderService.PageList(dto, pageNum, pageSize);
        return voList;
    }

    /**
     * 查询微信支付订单列表
     */
    @GetMapping("/list")
    public PageResult<OrderVO> ListText(OrderDTO dto,
                                    @RequestParam("pageNum") Integer pageNum,
                                    @RequestParam("pageSize") Integer pageSize) {
        //返回分页信息
        PageResult<OrderVO> voList = orderService.ListText(dto, pageNum, pageSize);
        return voList;
    }

    /**
     * 退款列表
     *
     * @param dto
     * @return
     */
    @GetMapping("/refundList")
    public PageResult<OrderVO> refundList(OrderDTO dto,
                                          @RequestParam("pageNum") Integer pageNum,
                                          @RequestParam("pageSize") Integer pageSize) {
        //返回分页信息
        PageResult<OrderVO> voList = orderService.refundList(dto, pageNum, pageSize);
        return voList;
    }

    /**
     * 查询微信支付订单列表 无分页
     */
    @GetMapping("/choiceList")
    public R choiceList(OrderDTO dto) {
        List<OrderVO> voList = orderService.choiceList(dto);
        return R.ok(voList, "ok");
    }

    /**
     * 获取微信支付订单详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(orderService.selectById(id));
    }

    /**
     * 新增微信支付订单
     */
    @Log(title = "微信支付订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody OrderDTO dto) {
        return toAjax(orderService.insert(dto));
    }

    /**
     * 修改微信支付订单
     */
    @Log(title = "微信支付订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OrderDTO dto) {
        return toAjax(orderService.updateOrderById(dto));
    }

    /**
     * 删除微信支付订单
     */
    @Log(title = "微信支付订单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(orderService.removeByOrderIds(Arrays.asList(ids)));
    }


    /**
     * 导出订单列表
     */
    @Log(title = "出库内容", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, OrderDTO dto) throws ParseException, IOException {
        List<OrderExcel> list = orderService.exportList(dto);
//        ExcelUtil<OrderExcel> util = new ExcelUtil<OrderExcel>(OrderExcel.class);
        excelUtils.exportExcel(response,list);
    }
    /**
     * 金额统计
     */
    @GetMapping("/count")
    public R orderCount(OrderDTO dto){
       OrderCount count = orderService.getOrderCount(dto);
       return R.ok(count,200,"ok");
    }
}
